const CFG = require('../config');
const EC = require('../comm/err-code');
const helper = require('../comm/api-helper');
const FUN = require('../comm/func');
const rCache = require('../model/redis_cache');
const tbPolicy = require('../model/tb_policy');
const dbPcyData = require('../model/model_data');
const HJSON = require('hjson');
const express = require('express');
const api = express();

// 获取指定id的策略详情，并带回其相关的策略选项信息
api.post('/get-with-type',async(req, resp) => {
  let param = req.body;
  let res = {code:EC.FAILD, msg:EC.FAILD_MSG};

  // 合法性校验
  let uInfo = await helper.CheckToken(param.token);
  if(!uInfo.uid) return resp.json({code:EC.AUTH_ERR, msg:EC.AUTH_ERR_MSG});

  // 获取策略详情
  if (param.id) {
    let itemInfo = await tbPolicy.findById(uInfo.uid, param.id);
    if(itemInfo == null){
      return resp.json({code:EC.PARAM_ERROR, msg:EC.PARAM_ERROR_MSG});
    }
    res.data = itemInfo;
  }

  // 获取策略选项
  if (res.data.type) {
    res.option = [];
    let typeNode = await rCache.getKey(rCache.N_Ptype, res.data.type);
    let typeObjs = HJSON.parse(typeNode);
    for (field of typeObjs) {
      field.options = helper.OptionsLevelHandle(uInfo.level, field.options);
      field.options_e = helper.OptionsLevelHandle(uInfo.level, field.options_e);
      field.explain = helper.OptionsLevelHandle(uInfo.level, field.explain);
      res.option.push(field); // display及level匹配才显示给用户
    }
    res.code = EC.SUCESS;
    res.msg = EC.SUCESS_MSG;
  } else {
    res.code = EC.NOT_FOUNT;
    res.msg = EC.NOT_FOUNT_MSG;
  }
  resp.json(res);
})

// 获取用户的所有策略
api.post('/get-of-user', async(req, resp) => {
  let param = req.body;
  let res = {code:EC.FAILD, msg:EC.FAILD_MSG};

  // 合法性校验
  let uInfo = await helper.CheckToken(param.token);
  if(!uInfo.uid) return resp.json({code:EC.AUTH_ERR, msg:EC.AUTH_ERR_MSG});

  if(!isVaild(param.fields)) param.fields = '*';

  // 获取策略详情
  let itemInfo = await tbPolicy.listByUid(uInfo.uid, param.fields);
  for(let i in itemInfo){
    itemInfo[i].ch_type = await rCache.get(rCache.N_Ptype, `all-types:${itemInfo[i].type}`, 'ch_name');
  }
  res.code = EC.SUCESS;
  res.msg = EC.SUCESS_MSG;
  res.data = itemInfo;
  resp.json(res);
})

// 获取指定产品下的所有策略
api.post('/get-of-product',async(req, resp) => {
  let param = req.body;
  let res = {code:EC.FAILD, msg:EC.FAILD_MSG};

  // 合法性校验
  let uInfo = await helper.CheckToken(param.token);
  if(!uInfo.uid) return resp.json({code:EC.AUTH_ERR, msg:EC.AUTH_ERR_MSG});

  // 获取策略详情
  if (param.prod_id) {
    let itemInfo = await tbPolicy.listByProdId(uInfo.uid, param.prod_id);
    for (let i in itemInfo) { // 处理每个策略
      itemInfo[i].ch_type = await rCache.get(rCache.N_Ptype, `all-types:${itemInfo[i].type}`, 'ch_name');
      if (itemInfo[i].table) itemInfo[i].record_count = await dbPcyData.rcdCount(uInfo.uid, itemInfo[i].table, itemInfo[i].id);
      else itemInfo[i].record_count = 0;
    }
    res.code = EC.SUCESS;
    res.msg = EC.SUCESS_MSG;
    res.data = itemInfo;
  }
  resp.json(res);
})

// 请求产品下的策略数
api.post('/get-num-for-product', async(req, resp) => {
  let param = req.body;
  let res = {code:EC.FAILD, msg:EC.FAILD_MSG, data:[]};

  // 合法性校验
  let uInfo = await helper.CheckToken(param.token);
  if(!uInfo.uid) return resp.json({code:EC.AUTH_ERR, msg:EC.AUTH_ERR_MSG});

  for (let id of param.prod_ids) {
    res.data.push({prod_id:id, policy_num:0});
  }

  // 获取产品下的策略数目
  if (param.prod_ids) {
    let retInfo = await tbPolicy.getProdPolicyCount(uInfo.uid, param.prod_ids);
    for (let info of retInfo) {
      let isIt = res.data.find((item)=>{return item.prod_id == info.prod_id});
      isIt.policy_num = info.policy_num;
    }
    res.code = EC.SUCESS;
    res.msg = EC.SUCESS_MSG;
  }
  resp.json(res);
})

// 新增策略
api.post('/add', async(req, resp) => {
  let param = req.body;
  let res = {code:EC.FAILD, msg:EC.FAILD_MSG};

  // 合法性校验
  let uInfo = await helper.CheckToken(param.token);
  if(!uInfo.uid) return resp.json({code:EC.AUTH_ERR, msg:EC.AUTH_ERR_MSG});

  // 参数校验
  if (!isInt(param.prod_id)) return resp.json({code:EC.PARAM_ERROR, msg:EC.PARAM_ERROR_MSG+':prod_id'});
  if (!isInt(param.policy_level)) return resp.json({code:EC.PARAM_ERROR, msg:EC.PARAM_ERROR_MSG+':policy_level'});
  if (!isInt(param.master)) return resp.json({code:EC.PARAM_ERROR, msg:EC.PARAM_ERROR_MSG+':master'});
  if (!isVaild(param.fields)) return resp.json({code:EC.PARAM_ERROR, msg:EC.PARAM_ERROR_MSG+':fields'});
  if (!isVaild(param.json)) return resp.json({code:EC.PARAM_ERROR, msg:EC.PARAM_ERROR_MSG+':json'});

  // level权限判定，todo: level外部传入，有漏洞，应改为内部获取
  if (uInfo.level < param.policy_level)
    return resp.json({code:EC.NO_LEVEL_AUTH, msg:EC.NO_LEVEL_AUTH_MSG});

  // 普通会员需要限制policy数量
  if (CFG.UserLevel[uInfo.level] == 'L0') {
    let policy_num = 0;
    let retInfo = await tbPolicy.getProdPolicyCount(uInfo.uid, param.prod_id);
    if (retInfo) {
      if (isVaild(retInfo[0]) && isVaild(retInfo[0].policy_num)) policy_num = retInfo[0].policy_num;
    } else { // db查数量错误
      return resp.json({code:EC.NUM_LIMITED_ERR, msg:EC.NUM_LIMITED_ERR_MSG});
    }

    if (policy_num > 2) { // 数目超限
      return resp.json({code:EC.NUM_LIMITED_ERR, msg:EC.NUM_LIMITED_ERR_MSG});
    }
  }

  // todo 用户存储限制

  let pcyItem = []; // 要保存到db的对象
  pcyItem.record_limit = 0; // 默认值，避免db报错
  pcyItem.brother = 0; // todo brother是否废弃
  let fields = param.fields;
  for(key in fields){ // fields 包括 type class name table record_limit debug
    pcyItem[key] = FUN.SBC_TO_DBC(fields[key]);
  }

  pcyItem.master = param.master;
  pcyItem.prod_id = param.prod_id;
  pcyItem.options = FUN.SBC_TO_DBC(param.json);
  pcyItem.db = (await helper.CheckAuth(param.token,'db')) ? 1 : 0;

  //处理算式非法内容， todo
  let calc=FUN.GetJsonValue(pcyItem.options, 'calc');
  if(calc){
    //if(hasXss($calc)) return ['code'=>CD_ILLEGAL_EXPRESSION,'msg'=>MSG_ILLEGAL_EXPRESSION];
  }

  let insertId = await tbPolicy.addItem(uInfo.uid, pcyItem);
  if(!insertId || parseInt(insertId) == 0){
    res.code = EC.FAILD;
    res.msg = EC.FAILD_MSG;
  } else {
    res.code = EC.SUCESS;
    res.msg = EC.SUCESS_MSG;
    helper.PolicyUpdateNotify('new');
  }

  resp.json(res);
})

// 删除策略，并不是直接删除，而是设置标志，并通知mq
api.post('/delete', async(req, resp) => {
  let param = req.body;
  let res = {code:EC.FAILD, msg:EC.FAILD_MSG};

  // 合法性校验
  let uInfo = await helper.CheckToken(param.token);
  if(!uInfo.uid) return resp.json({code:EC.AUTH_ERR, msg:EC.AUTH_ERR_MSG});

  // 参数校验
  if(!param.policy_id){
    return resp.json({code:EC.PARAM_ERROR, msg:EC.PARAM_ERROR_MSG});
  }

  // 删除策略
  let affectedNum = await tbPolicy.updateItem(uInfo.uid, param.policy_id, {del:1});
  if(affectedNum > 0){
    await dbPcyData.deletePcyId(uInfo.uid, param.policy_id); // 删除policy data
    res.code = EC.SUCESS;
    res.msg = EC.SUCESS_MSG;
    helper.PolicyUpdateNotify('del');
  }

  resp.json(res);
})

// 删除产品下所有策略，并不是直接删除，而是设置标志，并通知mq
api.post('/delete-of-product', async(req, resp) => {
  let param = req.body;
  let res = {code:EC.FAILD, msg:EC.FAILD_MSG};

  // 合法性校验
  let uInfo = await helper.CheckToken(param.token);
  if(!uInfo.uid) return resp.json({code:EC.AUTH_ERR, msg:EC.AUTH_ERR_MSG});

  // 参数校验
  if(!param.prod_id){
    return resp.json({code:EC.PARAM_ERROR, msg:EC.PARAM_ERROR_MSG});
  }

  // 删除产品下所有的策略数据
  dbPcyData.deletePcyIdByProd(uInfo.uid, param.prod_id); // 删除policy data

  // 遍历产品下的所以策略
  tbPolicy.listByProdId(uInfo.uid, param.prod_id, 'id').then(async(pcyIdInfos)=>{
    if (pcyIdInfos == null || pcyIdInfos.length == 0) return;

    for (let pcy of pcyIdInfos) { // 轮询删除策略
      await tbPolicy.updateItem(uInfo.uid, pcy.id, {del:1}); // 因为要发mq del信息，所以要同步等待所有的完成
      console.log(" - delete product[%d] policy[%d]", param.prod_id, pcy.id);
    }
    helper.PolicyUpdateNotify('del');
  }) // end then

  res.code = EC.SUCESS;
  res.msg = EC.SUCESS_MSG;
  resp.json(res);
})

// 修改策略
api.post('/modify', async(req, resp) => {
  let param = req.body;
  let res = {code:EC.FAILD, msg:EC.FAILD_MSG};

  // 合法性校验
  let uInfo = await helper.CheckToken(param.token);
  if (!uInfo.uid) return resp.json({code:EC.AUTH_ERR, msg:EC.AUTH_ERR_MSG});

  // 参数校验
  if (!param.id || !param.fields || !param.fields.options) {
    return resp.json({code:EC.PARAM_ERROR, msg:EC.PARAM_ERROR_MSG});
  }

  let fields = param.fields;
  // fields.options = FUN.SBC_TO_DBC(fields.options); // 全角转半角, 前端已经转码，所以此处不需要了
  // fields.options = FUN.AddSlashes(fields.options); // 添加转义符， todo 特殊字符限制
  // fields.options = '"' + fields.options + '"';
  // fields.options = "asdfa";
  // todo 存储限制
  if (fields.record_limit) {
  }
  // todo 处理算式非法内容


  // 存储数据库
  fields.init = 2; // 设置初始化标志为编辑后
  let affectedNum = await tbPolicy.updateItem(uInfo.uid, param.id, fields, param.prod_id);
  if (affectedNum > 0) {
    res.code = EC.SUCESS;
    res.msg = EC.SUCESS_MSG;
    helper.PolicyUpdateNotify('set');
  }

  resp.json(res);
})

// 修改策略单个字段
api.post('/modifyField', async(req, resp) => {
  let param = req.body;
  let res = {code:EC.FAILD, msg:EC.FAILD_MSG};

  // 合法性校验
  let uInfo = await helper.CheckToken(param.token);
  if (!uInfo.uid) return resp.json({code:EC.AUTH_ERR, msg:EC.AUTH_ERR_MSG});

  // 参数校验
  if (!param.id || !param.field || !param.value) {
    return resp.json({code:EC.PARAM_ERROR, msg:EC.PARAM_ERROR_MSG});
  }

  let fields = {};
  fields[param.field] = FUN.SBC_TO_DBC(param.value);

  //存储数据库
  fields.init = 2; // 设置初始化标志为编辑后
  let affectedNum = await tbPolicy.updateItem(uInfo.uid, param.id, fields);
  if (affectedNum > 0) {
    res.code = EC.SUCESS;
    res.msg = EC.SUCESS_MSG;
    helper.PolicyUpdateNotify('set');
  }

  resp.json(res);
})

module.exports = api;